home *** CD-ROM | disk | FTP | other *** search
- ; WINDOWS.S
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Scheme code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Text and Windows Manipulation Routines *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* Added full-screen, split-screen, text-mode, gc-screen mv*
- ;* - Jan 93: Added window-scroll-up/down, window-reverse-text! (mv) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
-
- ; The biggest legal size.
-
- (define max-console '(200 . 200))
-
- ; GC-SCREEN put the PCS-STATUS-WINDOW on the last line of CONSOLE
-
- (define (gc-screen)
- (let* ((xy (window-get-position 'console))
- (hl (let ((his-bet (window-get-size 'console)))
- (cons (- (min (car his-bet) (- (car max-console) (car xy))) 1)
- (min (cdr his-bet) (- (cdr max-console) (cdr xy))))))
- (at (window-get-attribute pcs-status-window 'text-attributes)))
- (window-set-attribute! pcs-status-window 'text-attributes 0)
- (window-clear pcs-status-window)
- (window-set-size! 'console (car hl) (cdr hl))
- (window-set-position! pcs-status-window (+ (car xy) (car hl)) (cdr xy))
- (window-set-size! pcs-status-window 1 (cdr hl))
- (window-set-attribute! pcs-status-window 'text-attributes at)
- (gc)
- *the-non-printing-object*))
-
- ; FULL-SCREEN makes the CONSOLE port as big as the video mode allows
-
- (define (full-screen)
- (window-set-position! 'console 0 0)
- (window-set-size! 'console (car max-console) (cdr max-console))
- (gc-screen))
-
-
- ; SPLIT-SCREEN put the CONSOLE port to the last n lines of screen
-
- (define (split-screen height)
- (full-screen)
- (window-set-position! 'console
- (- (car (window-get-size 'console)) height)
- 0)
- (gc-screen))
-
-
- ; TEXT-MODE change the video mode (same as Borland C/Turbo Pascal)
- ; Valid modes are :
- ; -------------------------------------------
- ; -1 Previous mode
- ; 0 Black & White 40 columns
- ; 1 Color 40 columns
- ; 2 Black & White 80 columns
- ; 3 Color 80 columns
- ; 7 Monochrom
- ; 64 Ega 43 lines / Vga 50 lines
-
- (define (text-mode mode)
- (%esc 18 mode)
- (full-screen))
-
-
- ; WINDOW-SCROLL-UP and WINDOW-SCROLL-DOWN scroll a window 1 line
- ; Optional parameters are: - first line to scroll
- ; - first line to stay (under scroll part)
- ; (default values are 0 & number-of-lines)
-
- (define window-scroll-up)
- (define window-scroll-down)
- (let ((window-scroll
- (lambda (func)
- (lambda (win . other)
- (if (window? win)
- (let* ((pos (window-get-position win))
- (siz (window-get-size win))
- (top (if (null? other) (car pos)
- (if (number? (car other))
- (+ (car pos) (car other))
- (%error-invalid-operand 'WINDOW-SCROLL (car other)))))
- (big (- (car siz) (- top (car pos))))
- (hei (if (null? (cdr other)) big
- (if (number? (cadr other))
- (min (- (cadr other) (car other)) big)
- (%error-invalid-operand 'WINDOW-SCROLL (cadr other))))))
- (if (> hei 0)
- (%esc func top (cdr pos) hei (cdr siz)
- (window-get-attribute win 'TEXT-ATTRIBUTES))))
- (%error-invalid-operand 'WINDOW-SCROLL win))))))
- (set! window-scroll-up (window-scroll 4)) ; %esc 4
- (set! window-scroll-down (window-scroll 5)) ; %esc 5
- )
-
- ; MAKE-WINDOW returns a "default" window object with the following
- ; attributes:
- ;
- ; Upper Left Hand Corner = 0,0
- ; Size (Lines, Columns) = 25,80 or 30,80 (the entire screen)
- ; Cursor Position = 0,0
- ; Text Color = White (on IBM, high intensity white)
- ; Border Color (if bordered) = Green (on IBM, low intensity green)
- ; Transcript Recording = Enabled
-
- (define make-window ; MAKE-WINDOW
- (lambda args
- (let ((label (car args))
- (bordered? (cadr args)))
- (if (or (null? label) (string? label))
- (let ((window (%make-window label)))
- (if bordered? (%reify-port! window 6 #b00001010)) ; green
- window)
- (begin
- (%error-invalid-operand 'MAKE-WINDOW label)
- '())))))
-
-
- ; WINDOW-CLEAR erases the data portion of a window (writes blanks using
- ; the current text attributes) and positions the cursor in position
- ; 0,0 (the upper left hand corner of the window). If the window is
- ; bordered, the border is re-drawn by this operation. This operation
- ; more properly may be considered a "window-initialize" operation.
-
- (define window-clear ; WINDOW-CLEAR
- (lambda (window)
- (if (or (window? window) (null? window))
- (%clear-window window)
- (begin
- (%error-invalid-operand 'WINDOW-CLEAR window)
- '()))))
-
-
- ; The "delete-window" function completely erases the area of the CRT which
- ; is covered by a given window, including the borders. This function
- ; accomplishes the erasing of the borders by expanding the dimensions
- ; of the window (temporarily) so that the borders are included in the
- ; data portion of the window; setting the border attribute to "no
- ; border"; and issuing a "%clear-window" operation to clear the text
- ; portion of the (temporarily) expanded window. After clearing the
- ; window and border, the original attributes of the window are
- ; restored.
- ;
- ; Note: when expanding the size of the window to account for the
- ; right and bottom borders, this routine takes advantage of the fact
- ; that %reify-port will not allow a window's boundaries to be set
- ; to be larger than the physical device size. Therefore, no check
- ; is performed to see if the right and bottom borders are off the
- ; screen.
-
- (define window-delete ; DELETE-WINDOW
- (lambda (window)
- (if (or (window? window) (null? window))
- (if (eqv? (%reify-port window 6) -1)
- (%clear-window window) ; if not bordered, just do a %clear-window
- (let ((ul-line (%reify-port window 2)) ; save current attributes
- (ul-col (%reify-port window 3)) ; for later restoration
- (n-lines (%reify-port window 4))
- (n-cols (%reify-port window 5))
- (b-attrib (%reify-port window 6))
- (t-lines '())
- (t-cols '()))
- (begin
- (when (> ul-line 0)
- (begin ; increase window size to include top border
- (%reify-port! window 2 (-1+ ul-line))
- (%reify-port! window 4 (1+ n-lines))))
- (when (> ul-col 0)
- (begin ; increase window size to include left border
- (%reify-port! window 3 (-1+ ul-col))
- (%reify-port! window 5 (1+ n-cols))))
- (set! t-lines (%reify-port window 4)) ; get new window size
- (set! t-cols (%reify-port window 5))
- (%reify-port! window 4 (1+ t-lines)) ; include bottom border
- (%reify-port! window 5 (1+ t-cols)) ; include right border
- (%reify-port! window 6 -1) ; indicate no border
- (%clear-window window)
- (%reify-port! window 2 ul-line) ; restore the original
- (%reify-port! window 3 ul-col) ; attributes to the user's
- (%reify-port! window 4 n-lines) ; window
- (%reify-port! window 5 n-cols)
- (%reify-port! window 6 b-attrib))))
- (begin
- (%error-invalid-operand 'WINDOW-DELETE window)
- '()))))
-
-
- ; WINDOW-GET-POSITION conses the coordinates of the upper left hand
- ; position of a window into a pair as: (line . column)
-
- (define window-get-position ; WINDOW-GET-POSITION
- (lambda (window)
- (if (or (window? window) (null? window))
- (cons (%reify-port window 2) (%reify-port window 3))
- (begin
- (%error-invalid-operand 'WINDOW-GET-POSITION window)
- '()))))
-
-
- ; WINDOW-GET-SIZE conses the number of lines and columns in a window
- ; (excluding the border columns, if any) into a pair as:
- ; (lines . columns)
-
- (define window-get-size ; WINDOW-GET-SIZE
- (lambda (window)
- (if (or (window? window) (null? window))
- (cons (%reify-port window 4) (%reify-port window 5))
- (begin
- (%error-invalid-operand 'WINDOW-GET-SIZE window)
- '()))))
-
-
- ; WINDOW-GET-CURSOR conses the line and column number of the current
- ; cursor position into a pair as: (line . column)
-
- (define window-get-cursor ; WINDOW-GET-CURSOR
- (lambda (window)
- (if (or (window? window) (null? window))
- (cons (%reify-port window 0) (%reify-port window 1))
- (begin
- (%error-invalid-operand 'WINDOW-GET-CURSOR window)
- '()))))
-
-
- ; The following routines modify the position, size, and cursor position
- ; of a window by side effecting the appropriate fields in a window
- ; object. An argument value of '() indicates that a particular
- ; field's value is to remain unchanged.
-
- (define window-set-position!)
- (define window-set-size!)
- (define window-set-cursor!)
- (letrec ((chk-and-set
- (lambda (window line column instruction-name L C)
- (cond
- ((not (or (window? window) (null? window)))
- (error (string-append "Invalid Window Argument to "
- (symbol->string instruction-name))
- window))
- ((and line
- (or (not (integer? line))
- (negative? line)))
- (error (string-append "Invalid Line Number to "
- (symbol->string instruction-name))
- line))
- ((and column
- (or (not (integer? column))
- (negative? column)))
- (error (string-append "Invalid Column Number to "
- (symbol->string instruction-name))
- column))
- (else
- (when line (%reify-port! window L line))
- (when column (%reify-port! window C column))
- window)))))
- (set! window-set-position! ; WINDOW-SET-POSITION!
- (lambda (window ul-line ul-col)
- (chk-and-set window ul-line ul-col
- 'WINDOW-SET-POSITION! 2 3)))
- (set! window-set-size! ; WINDOW-SET-SIZE!
- (lambda (window n-lines n-cols)
- (chk-and-set window n-lines n-cols
- 'WINDOW-SET-SIZE! 4 5)))
- (set! window-set-cursor! ; WINDOW-SET-CURSOR!
- (lambda (window cur-line cur-col)
- (chk-and-set window cur-line cur-col
- 'WINDOW-SET-CURSOR! 0 1))))
-
-
- ; Pop-Up window manipulation.
- ;
- ; "WINDOW-POPUP" preserves the data on the screen which will be
- ; covered by the pop-up window, initializes the window, and
- ; returns the pop-up window object to the caller.
- ;
- ; "WINDOW-POPUP-DELETE" restores the region of the CRT covered by a
- ; window created "WINDOW-POPUP" to its state prior to the
- ; pop-up window's appearance.
-
- (define window-popup)
- (define window-popup-delete)
- (let ((pop-up-list '()))
- (begin
- (set! window-popup ; WINDOW-POPUP
- (lambda (window)
- (if (or (window? window) (null? window))
- (begin
- (set! pop-up-list
- (cons (list window
- (window-save-contents window)
- (window-get-cursor window)
- (%reify-port window 6)
- (%reify-port window 7)
- (%reify-port window 8))
- pop-up-list))
- (window-delete window)
- (%clear-window window)
- window)
- (begin
- (%error-invalid-operand 'WINDOW-POPUP window)
- '()))))
- (set! window-popup-delete ; WINDOW-POPUP-DELETE
- (lambda (window)
- (let* ((saved-data (assq window pop-up-list))
- (reify-data (cdddr saved-data)))
- (when (not (null? saved-data))
- (window-restore-contents window (cadr saved-data))
- (window-set-cursor! window (caaddr saved-data) (cdaddr saved-data))
- (%reify-port! window 6 (car reify-data))
- (%reify-port! window 7 (cadr reify-data))
- (%reify-port! window 8 (caddr reify-data))
- (set! pop-up-list (delq! saved-data pop-up-list))
- window)))) ))
-
-
- ; The following routines get and set window attributes which are not
- ; modifiable by any of the above routines. It is necessary to explicitly
- ; name the attribute you wish to examine/modify.
-
- (define window-get-attribute)
- (define window-set-attribute!)
- (letrec ((attr-list '((border-attributes . 6)
- (text-attributes . 7)
- (window-flags . 8)))
- (check-and-map-args
- (lambda (window attribute)
- (if (or (window? window) (null? window))
- (cdr (assq attribute attr-list))
- #F))))
- (set! window-get-attribute
- (lambda (window attribute)
- (let ((mapped-attribute (check-and-map-args window attribute)))
- (if mapped-attribute
- (%reify-port window mapped-attribute)
- (begin
- (%error-invalid-operand-list 'WINDOW-GET-ATTRIBUTE
- window attribute)
- '())))))
- (set! window-set-attribute!
- (lambda (window attribute value)
- (let ((mapped-attribute (check-and-map-args window attribute)))
- (if (and mapped-attribute
- (integer? value)
- (< value 32767)
- (>= value -32768))
- (%reify-port! window mapped-attribute value)
- (begin
- (%error-invalid-operand-list 'WINDOW-SET-ATTRIBUTE!
- window attribute value)
- '()))))))
-
- ; WINDOW-REVERSE-TEXT helps to turn text to reverse, ie swaps text
- ; and background color of 'text-attributes
-
- (define (window-reverse-text! win)
- (if (window? win)
- (window-set-attribute!
- win
- 'text-attributes
- (bitwise-xor (window-get-attribute win 'text-attributes)
- #b01111111))
- (%error-invalid-operand-list 'WINDOW-REVERSE-TEXT win)))
-